#include <iostream>
#include <string>
#include <time.h>
#include <functional>
#include <pthread.h>
#include <vector>
#include <unistd.h>

// int gcnt = 100;
// 新线程
// void *ThreadRoutine (void *arg)
// {
//     const char* Thread_name = (const char*)arg;
//     //int cnt = 5;
//     while(true)
//     {
//         std::cout << "i am  new thread: " << Thread_name << ", pid:" << getpid() <<std::endl;
//         //gcnt--;//因为在同一个地址空间，看到的都是同一份代码。
//         sleep(1);
//     }
//     pthread_exit(nullptr);
// }

// int main()
// {
//     //main就已经有进程了
//     pthread_t tid;
//     pthread_create(&tid,nullptr,ThreadRoutine,(void*)"thread 1");
//     //主线程

//     // pthread_t tid1;
//     // pthread_create(&tid1,nullptr,ThreadRoutine,(void*)"thread 2");

//     while(true)
//     {
//         //pid号一样
//         std::cout << "i am main thread" << ", pid: " << getpid()  <<std::endl;
//         sleep(1);
//     }
//     return 0;
//}

/* typedef std::function<void()> func_t*/ // c++11用法
using func_t = std::function<void()>;     // 包装器
const int threadnum = 5;
// 新线程
class ThreadData
{
public:
    ThreadData(const std::string &threadname, const uint64_t &ctime, func_t f)
        : _threadname(threadname), _createtime(ctime), _func(f)
    {
    }

public:
    std::string _threadname;
    uint64_t _createtime;
    func_t _func;
};

void print()
{
    std::cout << "我是线程执行的一部分" << std::endl;
}

void *ThreadRoutine(void *arg)
{
    // std::string threadname = (const char *)arg;
    ThreadData *td = static_cast<ThreadData *>(arg);
    int cnt = 5;
    while (cnt--)
    {
        std::cout << "Pthread" << "name:" << td->_threadname << " Ctime " << td->_createtime << " " << pthread_self() << std::endl;
        td->_func();

        // if("thread-4"==td->_threadname)
        // {
        //     std::cout << td->_threadname << "异常"<<std::endl;
        //     int a = 10;
        //     a /= 0; //触发异常
        // }
        // 一个线程崩溃，所有的都崩溃了。
        sleep(1);
    }
    pthread_exit(nullptr);
}

int main()
{
    std::vector<pthread_t> pthreads;
    for (int i = 0; i < threadnum; i++)
    {
        char threadname[64];
        pthread_t tid;
        snprintf(threadname, sizeof(threadname), "%s-%d", "thread", i);
        ThreadData *td = new ThreadData(threadname, (uint64_t)time(nullptr), print);
        pthread_create(&tid, nullptr, ThreadRoutine, td);
        pthreads.push_back(tid);

        sleep(1);
        pthread_join(tid, nullptr);

        std::cout << "pthread done" << std::endl;
    }

    std::cout << "thread id:";
    for (auto &tid : pthreads)
    {
        std::cout << tid << " ";
    }
    std::cout << std::endl;

    std::cout << "main thread " << pthread_self() << std::endl;

    // 获取线程id号 pthread_self()
    //pthread_join(tid, nullptr);

    //std::cout << "pthread done" << std::endl;

    return 0;
}